home *** CD-ROM | disk | FTP | other *** search
- ;Assembly language macros for C compiler independence. Assemble with /mx
- ;to ensure mixed case symbols.
-
- ifndef MSC
- MSC equ 0
- endif
- ifndef TURBO
- TURBO equ 0
- endif
- ifndef AZTEC
- AZTEC equ 0
- endif
- if MSC + TURBO + AZTEC NE 1
- .err One and only one of MSC, TURBO, and AZTEC should be defined.
- endif
-
-
- ;Copyright, 1987, 1988, Russell Nelson
- ;Permission to use, copy, modify and distribute this software for any purpose
- ;and without fee is hereby granted, provided that the above copyright notice
- ;appears in all copies and that both that copyright notice and this permission
- ;appear in supporting documentation. Russell Nelson MAKES NO REPRESENTATIONS
- ;ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. IT IS PROVIDED
- ;"AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
-
- ; .xlist
-
- ;Note that symbols defined by these macros (pubproc, extproc, pubvar, extvar)
- ;should be referred by users of this package as 's@' where 's' is the defined
- ;symbol. This hides the compiler's underscore convention. For example,
- ; include pmacros.h
- ; extproc foo
- ; pubproc bar
- ; call foo@
- ; pend bar
-
- ;begin a public procedure and label it 'a'. If 'd' is absent, then default
- ;to what LARGECODE says, otherwise 'd' must be 'far' or 'near'.
- ;Terminated by pend.
- pubproc macro a,d
- cseg
- if AZTEC
- public a&_
- a&@ equ a&_
- else
- public _&a
- a&@ equ _&a
- endif
- ifb <d>
- ifdef LARGECODE
- if AZTEC
- a&_ proc far
- else
- _&a proc far
- endif
- first_param = 6
- else
- if AZTEC
- a&_ proc near
- else
- _&a proc near
- endif
- first_param = 4
- endif
- else ;ifb
- if AZTEC
- a&_ proc d
- else
- _&a proc d
- endif
- ifidn <d>,<far>
- first_param = 6
- else
- first_param = 4
- endif
- endif
- endm
-
- ;used internally to expand first_param and increment it.
- _param macro a,o,t,n
- a equ t ptr o[bp]
- first_param = first_param + n
- endm
-
-
- ;declare a parameter. Use byte, word, ptr, or fptr (function pointer).
- param macro a,t
- ifidn <t>,<byte>
- _param a,%first_param,byte,2
- endif
- ifidn <t>,<word>
- _param a,%first_param,word,2
- endif
- ifidn <t>,<ptr>
- ifdef LARGEDATA
- _param a,%first_param,dword,4
- else
- _param a,%first_param,word,2
- endif
- endif
- ifidn <t>,<fptr>
- ifdef LARGECODE
- _param a,%first_param,dword,4
- else
- _param a,%first_param,word,2
- endif
- endif
- endm
-
- ;load a data pointer.
- ldptr macro off_reg,var,seg_reg
- ifdef LARGEDATA
- l&seg_reg off_reg,var
- else
- mov off_reg,var
- endif
- endm
-
-
- ;define a public procedure with parameters, like so:
- ;procdef foo, <<bar, word>, <baz, ptr>>
- ;Terminated by pret, pend
- procdef macro n,a
- pubproc n
- irp one_param,<a>
- param one_param
- endm
- push bp
- mov bp,sp
- endm
-
- ;return from a procedure with parameters. Pairs with procdef
- pret macro
- pop bp
- ret
- endm
-
- ;end a public procedure. Pairs with pubproc
- pend macro a
- if AZTEC
- a&_ endp
- else
- _&a endp
- endif
- csegend
- endm
-
- ;define an external procedure called 'a'. If 'd' is absent, then default
- ;to what LARGECODE says, otherwise 'd' must be 'far' or 'near'.
-
- extproc macro a,d
- ifb <d>
- ifdef LARGECODE
- if AZTEC
- extrn a&_: far
- else
- extrn _&a: far
- endif
- else
- if AZTEC
- extrn a&_: near
- else
- extrn _&a: near
- endif
- endif
- else ;ifb
- if AZTEC
- extrn a&_: d
- else
- extrn _&a: d
- endif
- endif
- if AZTEC
- a&@ equ a&_
- else
- a&@ equ _&a
- endif
- endm
-
- ;open the code segment
- cseg macro
- if AZTEC
- codeseg segment byte public 'code'
- assume cs:codeseg,ds:dataseg
- endif
- if TURBO
- _TEXT segment byte public 'CODE'
- dgroup group _DATA
- assume cs:_TEXT,ds:dgroup
- endif
- if MSC
- _TEXT SEGMENT WORD PUBLIC 'CODE'
- assume cs:_TEXT,ds:DGROUP
- endif
- endm
-
- ;close the code segment
- csegend macro
- if AZTEC
- codeseg ends
- endif
- if TURBO or MSC
- _TEXT ends
- endif
- endm
-
- ;assume that the ds is the code segment
- dscode macro
- if AZTEC
- assume ds:codeseg
- endif
- if TURBO or MSC
- assume ds:_TEXT
- endif
- endm
-
-
- ;Return the data segment
- getds macro
- if AZTEC
- mov ax,dataseg
- endif
- if TURBO
- mov ax,dgroup
- endif
- if MSC
- mov ax,DGROUP
- endif
- endm
-
-
- ;open the data segment
- dseg macro
- if AZTEC
- dataseg segment word public 'data'
- endif
- if TURBO or MSC
- _DATA segment word public 'DATA'
- endif
- endm
-
- ;close the data segment
- dsegend macro
- if AZTEC
- dataseg ends
- endif
- if TURBO or MSC
- _DATA ends
- endif
- endm
-
- ;define a public variable
- ;use it like so: pubvar a,<dw 0>
- pubvar macro n,d
- if AZTEC
- public n&_
- n&_ d
- n&@ equ n&_
- endif
- if TURBO or MSC
- public _&n
- _&n d
- n&@ equ _&n
- endif
- endm
-
- ;define an external variable
- ;use it like so: extvar a,word
- ; or extvar a,byte
- extvar macro n,d
- if AZTEC
- extrn n&_: d
- n&@ equ n&_
- endif
- if TURBO or MSC
- extrn _&n: d
- n&@ equ _&n
- endif
- endm
-
- ; Conditional DS save/restore macros
- pushds macro
- ifdef LARGEDATA
- push ds
- endif
- endm
-
- popds macro
- ifdef LARGEDATA
- pop ds
- endif
- endm
-
- ; Conditional ES save/restore macros
- pushes macro
- ifdef LARGEDATA
- push es
- endif
- endm
-
- popes macro
- ifdef LARGEDATA
- pop es
- endif
- endm
-
- ;define the segments so that they exist.
- dseg
- dsegend
- if MSC
- CONST SEGMENT WORD PUBLIC 'CONST'
- CONST ENDS
- _BSS SEGMENT WORD PUBLIC 'BSS'
- _BSS ENDS
- DGROUP GROUP CONST,_BSS,_DATA
- endif
- cseg
- csegend
-
- ;define an interrupt handler.
- inthandler macro xxxname,xxxnum
-
- dseg
- extvar sssave,word
- extvar spsave,word
- extvar intstk,byte
- dsegend
-
- extproc doret
- extproc xxxname&int
-
- pubproc xxxname&xxxnum&vec
-
- cli ; this code is not re-entrant, so make sure it
- ; is not interrupted. some multi-taskers
- ; intercept interrupt handlers, so be careful!
-
- push ax ; save ax first.
- push ds ; save on user stack
- getds
- mov ds,ax
-
- mov sssave@,ss ; stash user stack context
- mov spsave@,sp
-
- mov ss,ax ; set up interrupt stack
- lea sp,intstk@
-
- push bx ; save user regs on interrupt stack
- push cx
- push dx
- push bp
- push si
- push di
- push es
-
- ifndef LARGEDATA
- mov es,ax ; small data assumes ES == DS
- endif
-
- if TURBO or MSC
- cld ; in case "movsb" or "movsw" is used
- endif
-
- mov ax,xxxnum ; arg for service routine
- push ax
- call xxxname&int@
- pop ax
- jmp doret@
- pend xxxname&xxxnum&vec
-
- endm
-
- assume cs:nothing,ds:nothing,es:nothing,ss:nothing
-
- ; .list
-